package com.nanbei.a05;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

import java.util.Objects;
import java.util.Set;

/**
 * @ClassDescription: @Bean 注解解析
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/11/14 14:07
 */
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        try{
            CachingMetadataReaderFactory readerFactory = new CachingMetadataReaderFactory();
            MetadataReader metadataReader = readerFactory.getMetadataReader(new ClassPathResource("com/nanbei/a05/Config.class"));
            Set<MethodMetadata> methods = metadataReader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata method : methods) {
                String initMethod = Objects.requireNonNull(method.getAnnotationAttributes(Bean.class.getName())).get("initMethod").toString();
                // 构建bean定义
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
                builder.setFactoryMethodOnBean(method.getMethodName(),"config");
                // 设置自动装配模式
                builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                if (initMethod.length() > 0 ){
                    builder.setInitMethodName(initMethod);
                }
                AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
                // 获取bean 工厂 ，注册bean定义
                if (configurableListableBeanFactory instanceof DefaultListableBeanFactory){
                    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;
                    beanFactory.registerBeanDefinition(method.getMethodName(),beanDefinition);
                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
